<?php

    /**
     * @package      Modules
     * @subpackage   Base_Classes_Utils
     *
     * @license      GNU Lesser General Public Licence see LICENCE-LGPL file or http://www.gnu.org/licenses/lgpl.html
     */
    abstract class Base_Classes_Utils_TableSchema
    {

    ////////////////////////////////////////////////////////////////////////////
    //                                 Methods                                //
    ////////////////////////////////////////////////////////////////////////////

        /**
        * Gets the schema from a Doctrine record
        *
        * @param        Doctrine_Record      $record
        * @param        array                $bind
        * @return       array
        */
        public static function getSchemaFromRecord(Doctrine_Record $record, $bind = array('*' => true))
        {
            $tableSchema    = array();
            $exists         = $record->exists();

            foreach ($record->getTable()->getColumns() as $key => $value) {
                // Retrieves columns informations
                $keys     = array_keys($record->getData());
                $fields   = array();

                foreach ($keys as $field) {
                    $fields[strtolower($field)] = $field;
                }

                if (isset($fields[strtolower($key)])) {
					$fieldname		= $fields[strtolower($key)];
                    $_value			= $record->$fieldname;

//                    if (!$exists && $value['type'] == 'string') {
//                        $_value = '';
//                    }

					if (in_array($value['type'], array('timestamp', 'date', 'time'))) {
						$dateTime = new Zend_Date($record->$fieldname, Zend_Date::ISO_8601);

						$_value	= array('date'		=> $dateTime->get(Zend_Date::DAY) .'/'. $dateTime->get(Zend_Date::MONTH) .'/'. $dateTime->get(Zend_Date::YEAR),
										'time'		=> $dateTime->get(Zend_Date::HOUR) .':'. $dateTime->get(Zend_Date::MINUTE));
                    }

                    $validators = array();
                    foreach($value as $validatorKey => $validator) {
                        if (!in_array($validatorKey, array('type', 'length', 'values'))) {
                            $validators[$validatorKey] = $validator;
                        }
                    }

                    $tableSchema[$fieldname]  = array(  'type'      => $value['type'],
                                                        'length'    => $value['length'],
                                                        'values'    => isset($value['values']) ? $value['values'] : '',
                                                        'value'		=> $_value,
                                                        'readonly'  => false,
                                                        'validators'=> $validators);
                }
            }

            if ($record->hasRelation('Translation')) {
                // Record is i18n
                $className      = get_class($record) .'Translation';
                $translation    = new $className();
                $columns        = $translation->getTable()->getColumns();

                $keys           = array_keys($translation->getData());

                $languages      = Doctrine_Query::create()
                                    ->select('cl.country_id, cl.language_id, c.code, l.code')
                                    ->from('DbCountryLanguage cl')
                                    ->leftJoin('cl.DbLanguage l')
                                    ->leftJoin('cl.DbCountry c')
                                    ->where('cl.displayInBack = ?', true)
                                    ->execute(array(), Doctrine::HYDRATE_ARRAY);

                $defaultNamespace   = new Zend_Session_Namespace('Default');
                $currentLanguage    = $defaultNamespace->language;

                foreach ($keys as $key) {
                    if (!in_array($key, array('id', 'lang'))) {
                        $value              = array();
                        $languageCodes      = array();

                        foreach($languages as $language) {
                            $languageCode       = $language['DbLanguage']['code'] .'_'. $language['DbCountry']['code'];
                            $languageCodes[]    = $languageCode;

                            if (isset($record->Translation[$languageCode]->$key)) {
                                $value[$languageCode] = $record->Translation[$languageCode]->$key;
                            } else {
                                $value[$languageCode] = '';
                            }
                        }

                        $tableSchema[$key] = array( 'type'      => $columns[$key]['type'],
                                                    'i18n'      => true,
                                                    'length'    => $columns[$key]['length'],
                                                    'values'    => $languageCodes,
                                                    'value'		=> $value,
                                                    'validators'=> array());
                    }
                }
            }

            if ($record->getTable()->getRelations()) {
                // Record has relations
                
                $relations      = array();
                $relations1on1  = array();

                foreach ($tableSchema as $key => $field) {
                    foreach ($record->getTable()->getRelations() as $class => $relation) {

                        if (strtolower($key) == strtolower($relation->getLocalFieldName()) && $relation->getLocalFieldName() != 'id') {
							$alias				= $relation->getAlias(); 

                            unset($tableSchema[$key]);

                            $values = array();
                            if ($alias != 'Translation' && (($bind['*'] === true) || ($bind[$alias] === true))) {
                                $tempValues = Doctrine_Query::create()->from($relation->getClass() .' o')->whereIn('o.status', array(DbBase::ENABLED, DbBase::DISABLED))->execute();
                                foreach ($tempValues as $id => $value) {
                                    $values[$id] = array($value->id, (($value->__toString() == '') ? $value->id : $value->__toString()));
                                }
                            }

                            $tableSchema[$alias] = array(   'type'      => 'relation1to1',
                                                            'relation'  => $relation,
                                                            'values'    => $values,
        													'value'		=> '',
                                                            'readonly'  => false,
                                                            'validators'=> array());

							if ($record->exists()) {
								$identifier	= $record->$alias->identifier();

								if (isset($identifier['id'])) {
									$tableSchema[$alias]['value']	= $identifier['id'];
								}
                            }

                            $relations1on1[] = $relation->getAlias();

                        } else if ($relation->getLocalFieldName() != 'id') {
                            $relations[$relation->getAlias()] = $relation;
                        }
                    }
                }

                foreach ($relations as $alias => $relation) {
                    if (!in_array($alias, $relations1on1)) {
                        $values         = array();
                        $objectValue    = array();
                        if ($alias != 'Translation') {

                            if (($bind['*'] === true) || ($bind[$alias] === true)) {
                                $tempValues = Doctrine_Query::create()->from($relation->getClass() .' o INDEXBY o.id')->whereIn('o.status', array(DbBase::ENABLED, DbBase::DISABLED))->execute();
                                foreach($tempValues as $id => $value) {
                                    $values[$id] = array($value->id, (($value->__toString() == '') ? $value->id : $value->__toString()));
                                }
                            

                                $refClass   = $relation->getAssociationTable()->name;
                                $references = $record->$refClass;
                                $foreignKey = $relation->getForeignFieldName();

                                foreach($references as $reference) {
                                    if (is_object($reference) && !($reference instanceof Doctrine_Null)) {
                                        $foreignValue   = $reference->$foreignKey;
                                        $objectValue[]  = $foreignValue;
                                    }
                                }
                            }

                            $tableSchema[$alias] = array(   'type'      => 'relation1toN',
                                                            'relation'  => $relation,
                                                            'values'    => $values,
                                                            'value'		=> $objectValue,
                                                            'readonly'  => false,
                                                            'validators'=> array());
                        }
                    }
                }
            }

            if ($record->getTable()->getTree()) {
                // Tree structure (nested set)
                $class                  = get_class($record);
                $tableSchema[$class]    = array('class'     => get_class($record),
                                                'type'      => 'nested',
                                                'values'    => (($bind['*'] === true) || ($bind['Nested'] === true)) ? Doctrine_Query::create()->from($class .' o INDEXBY o.id')->whereIn('o.status', array(DbBase::ENABLED, DbBase::DISABLED))->execute() : array(),
                                                'value'     => '',
                                                'select'    => false,
                                                'readonly'  => false);
            }

            return array('default' => $tableSchema);
        }
    }